package androidex;


import android.serialport.SerialPort;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Objects;


public class SerialHelper implements RFIDInterface, RFIDInterface.CallbackListener, RFIDInterface.RFID_Callbacklistener {
    private SerialPort mSerialPort;
    private OutputStream mOutputStream;
    private InputStream mInputStream;
    private ReadThread mReadThread;
    private String sPort;
    private int iBaudRate;
    private boolean _isOpen;
    private static CallbackListener callbackListener;
    private static RFID_Callbacklistener rfid_callbacklistener;
    private static Read_Callbacklistener read_callbacklistener;
    private static Temp_Callbacklistener temp_callbacklistener;
    private int CMDType = 0;   // 0:其他指令 1:盘点  2:读取标签
    private ArrayList<ReadTagData> readlist = new ArrayList<>();
    private ArrayList<String> writelist = new ArrayList<>();

    private boolean Select = false; // F 解绑  T  绑定

    public SerialHelper() {

    }

    public void open() throws SecurityException, IOException, InvalidParameterException {
        this.mSerialPort = new SerialPort(new File(this.sPort), this.iBaudRate, 0);
        this.mOutputStream = this.mSerialPort.getOutputStream();
        this.mInputStream = this.mSerialPort.getInputStream();
        this.mReadThread = new ReadThread();
        this.mReadThread.start();
        this._isOpen = true;
    }

    public void close() {
        if (this.mInputStream != null) {
            try {
                mInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (this.mOutputStream != null) {
            try {
                mOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (this.mReadThread != null) {
            this.mReadThread.interrupt();
        }

        if (this.mSerialPort != null) {
            this.mSerialPort.close();
            this.mSerialPort = null;
        }
        this._isOpen = false;
    }

    public boolean setBaudRate(int iBaud) {
        if (this._isOpen) {
            return false;
        } else {
            this.iBaudRate = iBaud;
            return true;
        }
    }

    public boolean setPort(String sPort) {
        if (this._isOpen) {
            return false;
        } else {
            this.sPort = sPort;
            return true;
        }
    }


    /**
     * 发送串口指令（字符串）
     * <p>
     * Hex String数据指令
     */
    public void sendHex(String sHex) {
        byte[] bOutArray = FuncUtil.String2Byte(sHex);
        byte[] Send_CMD = new byte[bOutArray.length + 1];
        System.arraycopy(bOutArray, 0, Send_CMD, 0, bOutArray.length);
        Send_CMD[bOutArray.length] = getXor(bOutArray);  //取校验
        try {
            this.mOutputStream.write(Send_CMD);
            this.mOutputStream.flush();
            Log.e("TAG", "串口发送" + FuncUtil.bytesToHexString(Send_CMD));

        } catch (IOException var3) {
            var3.printStackTrace();
        }

    }

    private int Len;

    private class ReadThread extends Thread {
        private ReadThread() {
        }

        public void run() {
            super.run();
            while (!this.isInterrupted()) {
                try {
                    if (SerialHelper.this.mInputStream == null) {
                        return;
                    }
                    Len = SerialHelper.this.mInputStream.available();
                    byte[] buffer = new byte[Len];
                    Len = SerialHelper.this.mInputStream.read(buffer, 0, Len);
                    //Log.e("TAG", "run Data: " + FuncUtil.bytesToHexString(buffer));
                    if (Len > 0) {
                        Log.e("TAG", "run CMDType: " + CMDType);
                        if (CMDType == 1) {        //盘点数据
                            Log.e("TAG", "盘点 Data: " + FuncUtil.bytesToHexString(buffer));
                            RecieveData_Pandian(buffer);
                        } else if (CMDType == 0) {  //其他指令
                            Log.e("TAG", "设置 Data: " + FuncUtil.bytesToHexString(buffer));
                            RecieveData(buffer);
                        } else if (CMDType == 2) {    //锁定灭活
                            ReadDAta(buffer);
                            Log.e("TAG", "锁定灭活标签 Data: " + FuncUtil.bytesToHexString(buffer));
                        } else if (CMDType == 3) {  //写标签
                            writedata(buffer);
                            Log.e("TAG", "写标签 Data: " + FuncUtil.bytesToHexString(buffer));
                        } else if (CMDType == 4) {
                            readbuffer(buffer);
                            Log.e("TAG", "读标签数据 Data: " + FuncUtil.bytesToHexString(buffer));
                        } else if (CMDType == 5) {
                            gjbbuffer(buffer);
                            Log.e("TAG", "擦除标签数据 Data: " + FuncUtil.bytesToHexString(buffer));
                        } else if (CMDType == 6) {
                            readtempbuffer(buffer);
                            Log.e("TAG", "设置温度标签 Data: " + FuncUtil.bytesToHexString(buffer));
                        } else if (CMDType == 7) {
                            RecieveData_Pandiantemp(buffer);
                            Log.e("TAG", "读温度标签 Data: " + FuncUtil.bytesToHexString(buffer));
                        }

                    }
                } catch (Throwable var4) {
                    Log.e("error", Objects.requireNonNull(var4.getMessage()));
                    return;
                }

            }

        }
    }

    /**
     * *盘点
     **/

    private void clean_pandian() {
        rfid_ptr = 0;
        Buffer = new byte[1024000];
        position = 0;
        CMDType = 1;
        po = 0;
    }

    private byte[] Buffer = new byte[1024000];
    private int position = 0;
    private int rfid_ptr = 0;
    private String Type = ": ";
    private int po = 0;  //起始地

    private void RecieveData_Pandian(byte[] data) {
        System.arraycopy(data, 0, Buffer, position, data.length);
        position = position + data.length;
        /**盘点数据口*/
        int data_len = 0; //每帧数据长度         BD 00 81 01 12 2F
        if (position > po + 3) {
            while (true) {
                data_len = Buffer[3 + po] + 5;
                if (position > po + data_len) {
                    byte[] onedata = new byte[data_len];
                    System.arraycopy(Buffer, po, onedata, 0, onedata.length);
                    if (onedata[4] == 0x00) {//成功盘道
                        if (onedata[5] == 0x01) {
                            Type = ":ISO";
                        } else if (onedata[5] == 0x04) {
                            Type = ":GJB";
                        }         // 1 iso   4  GJB
                        rfid_ptr = (onedata[15] & 0xff);
                        byte[] single = new byte[rfid_ptr];
                        System.arraycopy(onedata, 16, single, 0, rfid_ptr);
                        rfid_callbacklistener.rfid_Callback(true, FuncUtil.bytesToHexString(single) + Type);
                        Log.e("TAG", "rfid_callbacklistener: " + FuncUtil.bytesToHexString(single) + Type);
                    }
                    po += data_len;
                } else {
                    if (data_len == 6) {
                        byte[] Ldata = new byte[data_len];
                        System.arraycopy(Buffer, po, Ldata, 0, data_len);
                        if ((Ldata[2] == (byte) 0x5D | Ldata[2] == (byte) 0x3D) && Ldata[4] == 0x00) {
                            rfid_callbacklistener.rfid_Callback(true, "停止盘点");
                        } else if (Ldata[2] == (byte) 0x81) {
                            rfid_callbacklistener.rfid_Callback(true, "盘点" + Erdata(Ldata[4]));
                        }
                    }
                    break;
                }
            }
        }
    }

    /*********************读标签数据************************/

    private void clean_readbuffer() {
        Buffer3 = new byte[1024000];
        position3 = 0;
        po3 = 0;
        CMDType = 4;
    }

    private byte[] Buffer3 = new byte[1024000];
    private int position3 = 0;
    int data_len3 = 0; //每帧数据长度
    int po3 = 0;  //起始地址
    private ArrayList<String> RFID_data3 = new ArrayList<>();

    private void readbuffer(byte[] data) {
        System.arraycopy(data, 0, Buffer3, position3, data.length);
        position3 = position3 + data.length;
        if (position3 > po3 + 3) {//接受到每帧的数据长度字符 进入循环
            while (true) {
                data_len3 = Buffer3[3 + po3] + 5; //一帧数据长度
                if (position3 > po3 + data_len3) {
                    byte[] onedata = new byte[data_len3];
                    System.arraycopy(Buffer3, po3, onedata, 0, onedata.length);
                    if (onedata[4] == 0x00 && (onedata[5] == (byte) 0xFF | onedata[5] == (byte) 0x00)) {  //数据有效//成功盘道
                        int lens = onedata[11];
                        int lena = onedata[lens + 12] * 2;
                        byte[] name = new byte[lens];
                        byte[] data_tag = new byte[lena];
                        System.arraycopy(onedata, 12, name, 0, lens);
                        System.arraycopy(onedata, lens + 13, data_tag, 0, lena);
                        ReadTagData readTagData = new ReadTagData();
                        readTagData.setUII(FuncUtil.bytesToHexString(name));
                        readTagData.setDatalen(String.valueOf(lena));
                        readTagData.setData(FuncUtil.bytesToHexString(data_tag));
                        read_callbacklistener.read_Callback("读标签", readTagData);
                    }
                    po3 += data_len3;
                } else {
                    if (data_len3 == 6) {
                        byte[] Sdata = new byte[data_len3];
                        System.arraycopy(Buffer3, po3, Sdata, 0, data_len3);
                        Log.e("TAG", "读标签: " + FuncUtil.bytesToHexString(Sdata));
                        if ((Sdata[2] == (byte) 0x5D | Sdata[2] == (byte) 0x3D) && Sdata[4] == 0x00) {
                            read_callbacklistener.read_Callback("停止读标签", null);
                            po3 += data_len3;
                        } else if (Sdata[2] == (byte) 0x82) {
                            read_callbacklistener.read_Callback("读标签" + Erdata(Sdata[4]), null);
                            po3 += data_len3;
                        }
                    }
                    break;
                }


            }
        }
    }

    /*********************GJB擦除标签数据************************/

    private void clean_GJBbuffer() {
        Buffer5 = new byte[1024000];
        position5 = 0;
        po5 = 0;
        CMDType = 5;
        data_len5 = 0;
    }

    private byte[] Buffer5 = new byte[1024000];
    private int position5 = 0;
    private int data_len5 = 0; //每帧数据长度
    private int po5 = 0;  //起始地址


    private void gjbbuffer(byte[] data) {
        System.arraycopy(data, 0, Buffer5, position5, data.length);
        position5 = position5 + data.length;
        /***擦除标签**/
        if (Buffer5[position5 - 6] == (byte) 0xBD && Buffer5[position5 - 5] == (byte) 0x00
                && Buffer5[position5 - 4] == (byte) 0x45 &&
                Buffer5[position5 - 3] == (byte) 0x01 && Buffer5[position5 - 2] == (byte) 0x12
                && Buffer5[position5 - 1] == (byte) 0xEB) {//擦除标签结束返回BD 00 45 01 12 EB
            if (position5 > 6) {
                byte[] datab = new byte[position5 - 6];
                System.arraycopy(Buffer5, 0, datab, 0, datab.length);
                //  拿到了读取的数组
                for (po5 = 0; po5 < datab.length; po5 = data_len5 + po5) {
                    data_len5 = (datab[3 + po5] & 0xff) + 5;
                    byte[] single = new byte[data_len5];
                    System.arraycopy(datab, po5, single, 0, data_len5);

                    if (single[4] == 0x00 && (single[5] == (byte) 0xFF | single[5] == (byte) 0x00)) {  //数据有效
                        if (callbackListener != null) {
                            callbackListener.callback(true, "擦除标签成功");
                        }
                    } else {
                        callbackListener.callback(false, "擦除标签失败" + "Status异常码：" + FuncUtil.Byte2Hex(single[4]) + "TagStatus异常码：" + FuncUtil.Byte2Hex(single[5]));
                    }
                }

            } else {
                if (callbackListener != null) {
                    callbackListener.callback(false, "擦除标签失败");
                }
            }
        }
    }

    /**
     * *灭活锁标签数据
     **/
    private void other_clean() {
        read_Buffer = new byte[1024000];
        readlist.clear();
        read_position = 0;
        read_rfid_ptr = 0;
        read_lengtha = 0;
        CMDType = 2;
    }

    private byte[] read_Buffer = new byte[1024000];
    private int read_position = 0;
    private int read_rfid_ptr = 0;
    private int read_lengtha = 0;

    private void ReadDAta(byte[] data) {

        System.arraycopy(data, 0, read_Buffer, read_position, data.length);
        read_position = read_position + data.length;
        /***灭活标签**/
        if (read_Buffer[read_position - 6] == (byte) 0xBD && read_Buffer[read_position - 5] == (byte) 0x00
                && read_Buffer[read_position - 4] == (byte) 0x61 &&
                read_Buffer[read_position - 3] == (byte) 0x01 && read_Buffer[read_position - 2] == (byte) 0x12
                && read_Buffer[read_position - 1] == (byte) 0xCF) {//灭活结束返回BD 00 61 01 12 CF
            if (read_position > 6) {
                byte[] datab = new byte[read_position - 6];
                System.arraycopy(read_Buffer, 0, datab, 0, datab.length);
                //  拿到了读取的数组
                for (read_lengtha = 0; read_lengtha < datab.length; read_lengtha = read_rfid_ptr + read_lengtha) {
                    read_rfid_ptr = (datab[3 + read_lengtha] & 0xff) + 5;
                    byte[] single = new byte[read_rfid_ptr];
                    System.arraycopy(datab, read_lengtha, single, 0, read_rfid_ptr);
//                    Log.e("list 数据", FuncUtil.bytesToHexString(single));
                    /*拿到一条完整数据**/
                    if (single[4] == 0x00 && (single[5] == (byte) 0xFF | single[5] == (byte) 0x00)) {  //数据有效
                        if (callbackListener != null) {
                            callbackListener.callback(true, "灭活标签成功");
                        }
                    } else {
                        callbackListener.callback(false, "灭活标签失败" + "Status异常码：" + FuncUtil.Byte2Hex(single[4]) + "TagStatus异常码：" + FuncUtil.Byte2Hex(single[5]));
                    }
                }

            } else {
                if (callbackListener != null) {
                    callbackListener.callback(false, "灭活标签失败");
                }
            }
        }
        /**锁标签**/
        if (read_Buffer[read_position - 6] == (byte) 0xBD && read_Buffer[read_position - 5] == (byte) 0x00
                && read_Buffer[read_position - 4] == (byte) 0x60 &&
                read_Buffer[read_position - 3] == (byte) 0x01 && read_Buffer[read_position - 2] == (byte) 0x12
                && read_Buffer[read_position - 1] == (byte) 0xCE) {//锁标签结束返回BD 00 60 01 12 CE
            if (read_position > 6) {
                byte[] datab = new byte[read_position - 6];
                System.arraycopy(read_Buffer, 0, datab, 0, datab.length);
                //  拿到了读取的数组
                for (read_lengtha = 0; read_lengtha < datab.length; read_lengtha = read_rfid_ptr + read_lengtha) {
                    read_rfid_ptr = (datab[3 + read_lengtha] & 0xff) + 5;
                    byte[] single = new byte[read_rfid_ptr];
                    System.arraycopy(datab, read_lengtha, single, 0, read_rfid_ptr);
                    /*拿到一条完整数据**/
                    if (single[4] == 0x00 && (single[5] == (byte) 0xFF | single[5] == (byte) 0x00)) {  //数据有效
                        if (callbackListener != null) {
                            callbackListener.callback(true, "锁标签操作成功");
                        }

                    } else {
                        callbackListener.callback(false, "锁标签操作失败" + "Status异常码:" + FuncUtil.Byte2Hex(single[4]) + "   TagStatus异常码:" + FuncUtil.Byte2Hex(single[5]));
                    }
                }

            } else {

                if (callbackListener != null) {
                    callbackListener.callback(false, "锁标签操作失败");
                }
            }
        }


        /*****************国军标********************/
        /***灭活标签**/
        if (read_Buffer[read_position - 6] == (byte) 0xBD && read_Buffer[read_position - 5] == (byte) 0x00
                && read_Buffer[read_position - 4] == (byte) 0x47 &&
                read_Buffer[read_position - 3] == (byte) 0x01 && read_Buffer[read_position - 2] == (byte) 0x12
                && read_Buffer[read_position - 1] == (byte) 0xE9) {//国军标 灭活结束返回 BD 00 47 01 12 E9
            if (read_position > 6) {
                byte[] datab = new byte[read_position - 6];
                System.arraycopy(read_Buffer, 0, datab, 0, datab.length);
                //  拿到了读取的数组
                for (read_lengtha = 0; read_lengtha < datab.length; read_lengtha = read_rfid_ptr + read_lengtha) {
                    read_rfid_ptr = (datab[3 + read_lengtha] & 0xff) + 5;
                    byte[] single = new byte[read_rfid_ptr];
                    System.arraycopy(datab, read_lengtha, single, 0, read_rfid_ptr);
//                    Log.e("list 数据", FuncUtil.bytesToHexString(single));
                    /*拿到一条完整数据**/
                    if (single[4] == 0x00 && (single[5] == (byte) 0xFF | single[5] == (byte) 0x00)) {  //数据有效
                        if (callbackListener != null) {
                            callbackListener.callback(true, "灭活标签成功");
                        }
                    } else {
                        callbackListener.callback(false, "灭活标签失败" + "Status异常码：" + FuncUtil.Byte2Hex(single[4]) + "TagStatus异常码：" + FuncUtil.Byte2Hex(single[5]));
                    }
                }

            } else {
                if (callbackListener != null) {
                    callbackListener.callback(false, "灭活标签失败");
                }
            }
        }
        /**锁标签**/
        if (read_Buffer[read_position - 6] == (byte) 0xBD && read_Buffer[read_position - 5] == (byte) 0x00
                && read_Buffer[read_position - 4] == (byte) 0x46 &&
                read_Buffer[read_position - 3] == (byte) 0x01 && read_Buffer[read_position - 2] == (byte) 0x12
                && read_Buffer[read_position - 1] == (byte) 0xE8) {//国军标 锁标签结束返回BD 00 46 01 12 E8
            if (read_position > 6) {
                byte[] datab = new byte[read_position - 6];
                System.arraycopy(read_Buffer, 0, datab, 0, datab.length);
                //  拿到了读取的数组
                for (read_lengtha = 0; read_lengtha < datab.length; read_lengtha = read_rfid_ptr + read_lengtha) {
                    read_rfid_ptr = (datab[3 + read_lengtha] & 0xff) + 5;
                    byte[] single = new byte[read_rfid_ptr];
                    System.arraycopy(datab, read_lengtha, single, 0, read_rfid_ptr);
                    /*拿到一条完整数据**/
                    if (single[4] == 0x00 && (single[5] == (byte) 0xFF | single[5] == (byte) 0x00)) {  //数据有效
                        if (callbackListener != null) {
                            callbackListener.callback(true, "锁标签操作成功");
                        }

                    } else {
                        callbackListener.callback(false, "锁标签操作失败" + "Status异常码:" + FuncUtil.Byte2Hex(single[4]) + "   TagStatus异常码:" + FuncUtil.Byte2Hex(single[5]));
                    }
                }

            } else {

                if (callbackListener != null) {
                    callbackListener.callback(false, "锁标签操作失败");
                }
            }
        }

    }


    /*********************设置温度标签数据************************/

    private void clean_readtempbuffer() {
        tmpBuffer_2 = new byte[10240];
        tmpposition_2 = 0;
        CMDType = 6;
    }

    private byte[] tmpBuffer_2 = new byte[10240];
    private int tmpposition_2 = 0;

    private void readtempbuffer(byte[] data) {
        if (data != null) {
            System.arraycopy(data, 0, tmpBuffer_2, tmpposition_2, data.length);
            Log.e("TAG", "readtempbuffer 调试: " + FuncUtil.bytesToHexString(data));
            tmpposition_2 = tmpposition_2 + data.length;
            if (tmpposition_2 == (tmpBuffer_2[3] + 5)) {
                byte[] datab = new byte[tmpposition_2];
                System.arraycopy(tmpBuffer_2, 0, datab, 0, datab.length);
                switch (datab[2]) {
                    case (byte) 0x2D:
                        if (datab[4] == 0x00) {  //执行成功
                            switch (datab[5]) {
                                case 0x00:
                                    callbackListener.callback(true, "获取成功，普通温度标签");
                                    break;
                                case 0x01:
                                    callbackListener.callback(true, "获取成功，悦和LTU31温度标签");
                                    break;
                                case 0x02:
                                    callbackListener.callback(true, "获取成功，宜链温度标签");
                                    break;
                                case 0x03:
                                    callbackListener.callback(true, "获取成功，悦和LTU32温度标签");
                                    break;
                            }
                        } else {
                            callbackListener.callback(false, "获取温度标签类型：" + Erdata(datab[4]));
                        }
                        break;
                    case (byte) 0x2C:
                        switch (datab[4]) {
                            case 0x00:
                                callbackListener.callback(true, "温度标签类型设置成功");
                                break;
                            case 0x01:
                                callbackListener.callback(true, "温度标签类型设置失败，参数错误");
                                break;
                            default:
                                callbackListener.callback(false, "温度标签类型设置失败：" + Erdata(datab[4]));
                                break;
                        }
                        break;
                    case (byte) 0x0D:
                        if (datab[4] == 0x00) {  //执行成功
                            switch (datab[5]) {
                                case 0x00:
                                case (byte) 0xFF:
                                    callbackListener.callback(true, "命令执行成功");
//                                    Log.e("TAG", "执行成功 调试: " + FuncUtil.bytesToHexString(data));
                                    break;
                                case 0x01:
                                    callbackListener.callback(true, "参数值错误或越界");
                                    break;
                                case 0x02:
                                    callbackListener.callback(true, "由于模块内部错误导致的命令执行失败");
                                    break;
                                case 0x12:
                                    callbackListener.callback(true, "没有盘点到标签或整个盘点命令执行完成");
                                    break;
                                case 0x14:
                                    callbackListener.callback(true, "标签响应超时");
                                    break;
                                case 0x15:
                                    callbackListener.callback(true, "解调标签响应错误");
                                    break;
                                case 0x17:
                                    callbackListener.callback(true, "认证失败");
                                    break;
                                case 0x21:
                                    callbackListener.callback(true, "PSAM模块无响应或响应错误");
                                    break;
                            }
                        } else {
                            callbackListener.callback(false, "设置温度标签" + Erdata(datab[4]));
                        }
                        break;

                }


            }
        }
    }

    /*********************读取温度标签数据************************/

    private void clean_pandiantemp() {
        rfid_ptrtemp = 0;
        Buffertemp = new byte[1024000];
        positiontemp = 0;
        CMDType = 7;
        potemp = 0;
    }

    private byte[] Buffertemp = new byte[1024000];
    private int positiontemp = 0;
    private int rfid_ptrtemp = 0;
    private String Typetemp = ": ";
    private int potemp = 0;  //起始地

    private void RecieveData_Pandiantemp(byte[] data) {
        System.arraycopy(data, 0, Buffertemp, positiontemp, data.length);
        positiontemp = positiontemp + data.length;
        /**盘点数据口*/
        int data_len = 0; //每帧数据长度         BD 00 81 01 12 2F
        if (positiontemp > potemp + 3) {
            while (true) {
                data_len = Buffertemp[3 + potemp] + 5;
                if (positiontemp > potemp + data_len) {
                    byte[] onedata = new byte[data_len];
                    System.arraycopy(Buffertemp, potemp, onedata, 0, onedata.length);
                    if (onedata[4] == 0x00) {//成功盘道
                        int lens = onedata[11];
                        int lena = onedata[lens + 12] * 2;
                        byte[] name = new byte[lens];
                        byte[] data_tag = new byte[lena];
                        System.arraycopy(onedata, 12, name, 0, lens);
                        System.arraycopy(onedata, lens + 13, data_tag, 0, lena);

                        float tempdata = (float) (((data_tag[0] << 8) & 0xFF00) + (data_tag[1] & 0xFF)) / 10.0F;
                        String temp = FuncUtil.bytesToHexString(data_tag);
                        Log.e("TAG", "读取温度 调试 data_tag: " + FuncUtil.bytesToHexString(data_tag));
                        Log.e("TAG", "读取温度 调试 计算结果: " + tempdata);

                        temp_callbacklistener.temp_Callback(true, FuncUtil.bytesToHexString(name) + ":" + tempdata);
                    }
                    potemp += data_len;
                } else {
                    if (data_len == 6) {
                        byte[] Ldata = new byte[data_len];
                        System.arraycopy(Buffertemp, potemp, Ldata, 0, data_len);
                        if ((Ldata[2] == (byte) 0x5D | Ldata[2] == (byte) 0x3D) && Ldata[4] == 0x00) {
                            temp_callbacklistener.temp_Callback(true, "停止读温度标签");
                        } else if (Ldata[2] == (byte) 0x81) {
                            temp_callbacklistener.temp_Callback(true, "温度标签" + Erdata(Ldata[4]));
                        }
                    }
                    break;
                }
            }
        }
    }


/****************************************/
    /**
     * *写标签
     **/

    private byte[] write_Buffer = new byte[1024];
    private int write_position = 0;
    private int write_rfid_ptr = 0;
    private int write_lengtha = 0;


    private void write_clean() {
        write_Buffer = new byte[1024 * 100];
        writelist.clear();
        write_position = 0;
        write_rfid_ptr = 0;
        write_lengtha = 0;
        CMDType = 3;
    }

    private void writedata(byte[] data) {
        count_write = 0;
        System.arraycopy(data, 0, write_Buffer, write_position, data.length);
        write_position = write_position + data.length;
        /**写标签数据口*/
        if (write_Buffer[write_position - 6] == (byte) 0xBD && write_Buffer[write_position - 5] == (byte) 0x00
                && write_Buffer[write_position - 4] == (byte) 0x5F &&
                write_Buffer[write_position - 3] == (byte) 0x01 && write_Buffer[write_position - 2] == (byte) 0x12
                && write_Buffer[write_position - 1] == (byte) 0xF1) {// ISO 写标签结束返回BD 00 5F 01 12 F1
            if (write_position > 6) {
                byte[] datab = new byte[write_position - 6];
                System.arraycopy(write_Buffer, 0, datab, 0, datab.length);
                //  拿到了写标签返回字节数组
                for (write_lengtha = 0; write_lengtha < datab.length; write_lengtha = write_rfid_ptr + write_lengtha) {
                    write_rfid_ptr = (datab[3 + write_lengtha] & 0xff) + 5;
                    byte[] single = new byte[write_rfid_ptr];
                    System.arraycopy(datab, write_lengtha, single, 0, write_rfid_ptr);
                    if (single[4] == 0x00 && (single[5] == 0x00 | single[5] == (byte) 0xFF)) {
                        writelist.add(FuncUtil.bytesToHexString(single));
                    }
                }
                if (writelist.size() > 0) {
                    if (callbackListener != null) {
                        for (int i = 0; i < writelist.size(); i++) {
                            callbackListener.callback(true, "写标签成功" + writelist.get(i));
                            breakout_write = true;
                        }
                    }
                } else {
                    if (callbackListener != null) {
                        callbackListener.callback(true, "写标签失败");
                        breakout_write = true;
                    }
                }
            } else {
                callbackListener.callback(false, "写标签" + Erdata(write_Buffer[4]));
                breakout_write = true;
            }
            /**国军标***/
        } else if (write_Buffer[write_position - 6] == (byte) 0xBD && write_Buffer[write_position - 5] == (byte) 0x00
                && write_Buffer[write_position - 4] == (byte) 0x44 &&
                write_Buffer[write_position - 3] == (byte) 0x01 && write_Buffer[write_position - 2] == (byte) 0x12
                && write_Buffer[write_position - 1] == (byte) 0xEA) {//国军标写标签结束返回BD 00 44 01 12
            if (write_position > 6) {
                byte[] datab = new byte[write_position - 6];
                System.arraycopy(write_Buffer, 0, datab, 0, datab.length);
                //  拿到了写标签返回字节数组
                for (write_lengtha = 0; write_lengtha < datab.length; write_lengtha = write_rfid_ptr + write_lengtha) {
                    write_rfid_ptr = (datab[3 + write_lengtha] & 0xff) + 5;
                    byte[] single = new byte[write_rfid_ptr];
                    System.arraycopy(datab, write_lengtha, single, 0, write_rfid_ptr);
                    if (single[4] == 0x00 && (single[5] == 0x00 | single[5] == (byte) 0xFF)) {
                        writelist.add(FuncUtil.bytesToHexString(single));
                    }
                }
                if (writelist.size() > 0) {
                    if (callbackListener != null) {
                        for (int i = 0; i < writelist.size(); i++) {
                            callbackListener.callback(true, "写标签成功" + writelist.get(i));
                            breakout_write = true;
                        }
                    }
                } else {
                    if (callbackListener != null) {
                        callbackListener.callback(true, "写标签失败");
                        breakout_write = true;
                    }
                }
            } else {
                callbackListener.callback(false, "写标签" + Erdata(write_Buffer[4]));
                breakout_write = true;
            }
        }
    }

    private boolean breakout_write = false;
    private int count_write = 0;

    private void ANNR_write() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (count_write < 8) {
                    try {
                        Thread.sleep(500);
                        count_write++;
                        Log.e("TAG", "run: ");
                        if (breakout_write) {
                            count_write = 0;
                            breakout_write = false;
                            break;
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (count_write == 8) {
                    if (callbackListener != null) {
                        callbackListener.callback(true, "写标签无响应，已停止");
                        Log.e("TAG", "run: 回调不为空");
                    }
                    count_write = 0;
                    breakout_write = false;
                    reciveClean();
                    String STOP = "BD005D00";
                    sendHex(STOP);
                }
            }
        }).start();
    }


/*****************************************/
    /**
     * 其他数据
     **/
    private void reciveClean() {
        Buffer_2 = new byte[10240];
        position_2 = 0;
        CMDType = 0;
    }

    private byte[] Buffer_2 = new byte[10240];
    private int position_2 = 0;

    private void RecieveData(byte[] data) {
        if (data != null) {
            System.arraycopy(data, 0, Buffer_2, position_2, data.length);
            Log.e("TAG", "RecieveData 调试: " + FuncUtil.bytesToHexString(data));
            position_2 = position_2 + data.length;
            if (position_2 == (Buffer_2[3] + 5)) {
                byte[] datab = new byte[position_2];
                System.arraycopy(Buffer_2, 0, datab, 0, datab.length);
                switch (datab[2]) {
                    case (byte) 0x83:  //设置链路参数
                        if (datab[4] == 0x00) {  //执行成功
                            switch (datab[5]) {
                                case 0x00:
                                    callbackListener.callback(true, "设置成功，协议代码：ISO 18000-63");
                                    break;
                                case 0x01:
                                    callbackListener.callback(true, "设置成功，协议代码：GB/T 29768");
                                    break;
                                case 0x02:
                                    callbackListener.callback(true, "设置成功，协议代码：GJB 7377.1");
                                    break;
                            }
                        } else {
                            callbackListener.callback(false, "设置链路参数" + Erdata(datab[4]));
                        }
                        break;
                    case (byte) 0x84:   //获取链路参数
                        if (datab[4] == 0x00) {  //执行成功
                            if (datab[5] == 0x00) {
                                switch (datab[6]) {
                                    case 0x00:
                                        callbackListener.callback(true, "协议代码：ISO 18000-63" + "链路模式索引:160 KHz, FM0，Tari = 12.5 us");
                                        break;
                                    case 0x01:
                                        callbackListener.callback(true, "协议代码：ISO 18000-63" + "链路模式索引:160 Khz Miller8，Tari = 12.5 us");
                                        break;
                                    case 0x02:
                                        callbackListener.callback(true, "协议代码：ISO 18000-63" + "链路模式索引:250 Khz FM0，Tari = 12.5 us");
                                        break;
                                    case 0x03:
                                        callbackListener.callback(true, "协议代码：ISO 18000-63" + "链路模式索引:320 Khz Miller4，Tari = 6.25 us");
                                        break;
                                }
                            } else if (datab[5] == 0x02) {
                                switch (datab[6]) {
                                    case 0x00:
                                        callbackListener.callback(true, "协议代码：GJB 7737.1" + "链路模式索引:160KHz,FM0，Tari=6.25us");
                                        break;
                                    case 0x01:
                                        callbackListener.callback(true, "协议代码：GJB 7737.1" + "链路模式索引:320KHz,Miller4，Tari=12.5us");
                                        break;
                                }//可增加其他协议
                            }
                        } else {
                            callbackListener.callback(false, "获取链路参数" + Erdata(datab[4]));
                        }
                        break;
                    case 0x10:
                        if (datab[4] == 0x00) { //盘点占空比参数设置
                            callbackListener.callback(true, "盘点占空比设置成功");
                        } else {
                            callbackListener.callback(false, "设置盘点占空比" + Erdata(datab[4]));
                        }
                        break;
                    case 0x11:
                        if (datab[4] == 0x00) { //盘点占空比参数获取
                            int a = (((datab[6] & 0xFF) << 24) + ((datab[7] & 0xFF) << 16) + ((datab[8] & 0xFF) << 8) + ((datab[9] & 0xFF)));
                            if (callbackListener != null)
                                callbackListener.callback(true, "盘点轮空间隔次数:" + datab[5] + "\r\n"
                                        + "盘点轮空延时:" + a + "ms");
                        } else {
                            callbackListener.callback(false, "获取盘点占空比" + Erdata(datab[4]));
                        }
                        break;
                    case 0x0F:   //恢复出厂
                        if (datab[4] == 0x00) { //保存参数成功
                            if (callbackListener != null)
                                callbackListener.callback(true, "恢复出厂设置成功");
                        } else {
                            callbackListener.callback(false, "恢复出厂设置" + Erdata(datab[4]));
                        }
                        break;
                    case 0x0E:
                        if (datab[4] == 0x00) { //保存参数成功
                            if (callbackListener != null)
                                callbackListener.callback(true, "保存参数成功");
                        } else {
                            callbackListener.callback(false, "保存参数" + Erdata(datab[4]));
                        }
                        break;

                    case 0x03:    //重启模块
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null)
                                callbackListener.callback(true, "重启成功");
                        } else {
                            callbackListener.callback(false, "重启" + Erdata(datab[4]));
                        }
                        break;
                    case 0x01:    //读取模块INFO
                        if (datab[4] == 0x00) {
                            byte[] HardVer = new byte[32];
                            System.arraycopy(datab, 5, HardVer, 0, 32);
                            byte[] FirmVer = new byte[32];
                            System.arraycopy(datab, 37, FirmVer, 0, 32);
                            byte[] SN_code = new byte[20];
                            System.arraycopy(datab, 69, SN_code, 0, 20);
                            byte[] MAC = new byte[6];
                            System.arraycopy(datab, 89, MAC, 0, 6);
                            String a = new String(FuncUtil.selectbyte(HardVer), StandardCharsets.US_ASCII);
                            String b = new String(FuncUtil.selectbyte(FirmVer), StandardCharsets.US_ASCII);
                            String c = new String(FuncUtil.selectbyte(SN_code), StandardCharsets.US_ASCII);
                            callbackListener.callback(true, "HardVer:" + a + "\r\n"
                                    + "FirmVer:" + b + "\r\n"
                                    + "SN_code:" + c + "\r\n"
                                    + "MAC:" + FuncUtil.bytesToHexString(MAC));

                        } else {
                            callbackListener.callback(false, "读取模块INFO" + Erdata(datab[4]));
                        }
                        break;
                    case 0x0C:       //设置/读取模块配置的协议掩码
                        switch (datab[3]) {
                            case 0x02:    //设置
                                if (datab[4] == 0x00) { //成功
                                    if (callbackListener != null)
                                        callbackListener.callback(true, "协议掩码设置成功");
                                } else {
                                    callbackListener.callback(false, "设置协议" + Erdata(datab[4]));
                                }
                                break;
                            case 0x04:   //读取
                                if (datab[4] == 0x00) { //成功
                                    switch (datab[6]) {
                                        case 0x01:
                                            if (callbackListener != null)
                                                callbackListener.callback(true, "ISO 18000-63 协议");
                                            break;
                                        case 0x02:
                                            if (callbackListener != null)
                                                callbackListener.callback(true, "GB/T 29768 协议");
                                            break;
                                        case 0x04:
                                            if (callbackListener != null)
                                                callbackListener.callback(true, "GJB 7377.1 协议");
                                            break;
                                        case 0x05:
                                            if (callbackListener != null)
                                                callbackListener.callback(true, "GJB && ISO 协议");
                                            break;
                                    }
                                } else {
                                    callbackListener.callback(false, "读取协议" + Erdata(datab[4]));
                                }
                                break;
                        }
                        break;
                    case 0x08://设置天线使能
                    case 0x09://读取天线装状态
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null)
                                callbackListener.callback(true, " 天线操作成功");
                        } else {
                            callbackListener.callback(false, "天线操作" + Erdata(datab[4]));
                        }
                        break;
                    case 0x15: //设置天线功率
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null)
                                callbackListener.callback(true, " 天线功率设置成功");
                        } else {
                            callbackListener.callback(false, "设置天线" + Erdata(datab[4]));
                        }
                        break;
                    case 0x16://获取天线功率
                        if (datab[4] == 0x00) { //成功
                            if (datab[6] == 0x01) {
                                int a = datab[7];
                                if (callbackListener != null)
                                    callbackListener.callback(true, " 天线1在位,功率为:" + a);
                            }
                        } else {
                            callbackListener.callback(false, "获取天线功率" + Erdata(datab[4]));
                        }
                        break;
                    case (byte) 0x85: //设置射频工作频率
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null)
                                callbackListener.callback(true, " 设置射频工作频率成功");
                        } else {
                            callbackListener.callback(false, "设置射频工作频率" + Erdata(datab[4]));
                        }
                        break;
                    case (byte) 0x86://读取射频工作频率
                        if (datab[4] == 0x00) { //成功
                            int fre_H = ((datab[7] << 8) & 0xFF00) + ((datab[8]) & 0xFF);
                            int fre_L = ((datab[9] << 8) & 0xFF00) + ((datab[10]) & 0xFF);
                            int fre_S = ((datab[11] << 8) & 0xFF00) + ((datab[12]) & 0xFF);
                            int cu = datab[13];
                            switch (datab[6]) {
                                case 0x00:  //CHINA-2；
                                    callbackListener.callback(true, "地域索引：CHINA-2 起始频率：" + fre_H + "." + fre_L + "MHz" + "频率步进:" + fre_S + "KHz" + "信道数：" + cu);
                                    break;
                                case 0x01:  //FCC；
                                    callbackListener.callback(true, "地域索引：FCC 起始频率：" + fre_H + "." + fre_L + "MHz" + "频率步进:" + fre_S + "KHz" + "信道数：" + cu);
                                    break;
                                case 0x04: //ETSI；
                                    callbackListener.callback(true, "地域索引：ETSI 起始频率：" + fre_H + "." + fre_L + "MHz" + "频率步进:" + fre_S + "KHz" + "信道数：" + cu);
                                    break;
                                case 0x05: //CHINA-1；
                                    callbackListener.callback(true, "地域索引：CHINA-1 起始频率：" + fre_H + "." + fre_L + "MHz" + "频率步进:" + fre_S + "KHz" + "信道数：" + cu);
                                    break;
                                case 0x06:  //自定义
                                    callbackListener.callback(true, "地域索引：自定义 起始频率：" + fre_H + "." + fre_L + "MHz" + "频率步进:" + fre_S + "KHz" + "信道数：" + cu);
                                    break;
                            }
                        } else {
                            callbackListener.callback(false, "读取射频工作频率" + Erdata(datab[4]));
                        }
                        break;
                    case (byte) 0x6B:  //选择标签 ISO
                    case (byte) 0x4B:  //选择标签  GJB
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null) {
                                if (Select) {
                                    callbackListener.callback(true, "选择标签成功");
                                } else {
                                    callbackListener.callback(true, "取消选择标签成功");
                                }
                            }

                        } else {
                            Select = !Select;//操作失败
                            callbackListener.callback(false, "操作标签" + Erdata(datab[4]));
                        }
                        break;

                    case (byte) 0x13:
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null)
                                callbackListener.callback(true, " 温度设置成功");

                        } else {
                            callbackListener.callback(false, "温度设置失败，模块不支持该值");
                        }
                        break;
                    case (byte) 0x14://获取
                        if (datab[4] == 0x00) { //成功
                            if (callbackListener != null)
                                callbackListener.callback(true, " 温度设置成功" + "温度：" + datab[5] + "℃" + "温度阈值：" + datab[6] + "℃");
                        }
                        break;
                    case (byte) 0x12://固件升级返回
                        //成功
                        if (callbackListener != null) {
                            callbackListener.callback(true, " 固件" + status(datab[4]));
                        }
                        break;
                    case (byte) 0xDD://日志
                        switch (datab[4]) {
                            case 0x00:
                                if (callbackListener != null) {
                                    byte[] log = new byte[datab[5]];
                                    System.arraycopy(datab, 6, log, 0, log.length);
                                    callbackListener.callback(true, " 日志" + FuncUtil.bytesToHexString(log));
                                }
                                break;
                            case 0x01:
                                if (callbackListener != null) {
                                    callbackListener.callback(true, " 日志" + "参数值错误或越界");
                                }
                                break;
                            case (byte) 0xFF:
                                if (callbackListener != null) {
                                    callbackListener.callback(true, " 日志" + "没有更多日志数据了");
                                }
                                break;
                        }
                        break;
                    case 0x5D:
                        if (datab[4] == 0x00) {
                            callbackListener.callback(true, "已停止");
                        }
                        break;
                }
            } else {   //BD 00 81 01 12 2F BD 00 5D 01 00 E1
                if (Buffer_2[0] == (byte) 0xBD && Buffer_2[4] == 0x12 && Buffer_2[6] == (byte) 0xBD && Buffer_2[8] == 0x5D && Buffer_2[10] == (byte) 0x00) {
                    callbackListener.callback(true, "已停止");
                }
            }
        }
    }

    private String status(byte a) {
        switch (a) {
            case 0x00:
                return "固件升级成功";
            case 0x01:
                return "固件太大";
            case 0x02:
                return "固件写入错误";
            case 0x03:
                return "传输已取消";
            case 0x04:
                return "传输数据丢失";
            case 0x05:
                return "固件接收失败";
        }
        return null;
    }

    /**
     * 字节转十六进制
     *
     * @param b 需要进行转换的byte字节
     * @return 转换后的Hex字符串
     */
    public static String byteToHex(byte b) {
        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() < 2) {
            hex = "0" + hex;
        }
        return hex;
    }

    /*******校验***/
    public static byte getXor(byte[] datas) {
        byte temp = datas[0];
        for (int i = 1; i < datas.length; i++) {
            temp ^= datas[i];
        }
        Log.e("TAG", "校验 getXor: " + byteToHex(temp));
        return temp;
    }

    /***ISO 与 国军标协议一致
     /***获取模块版本信息和SN码*/
    @Override
    public void HSURM_GET_INFO(CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String cmd = "BD000100";
        sendHex(cmd);
    }

    /***ISO 与 国军标协议一致
     * 重启模块
     **/
    @Override
    public void HSURM_REBOOT(CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String cmd = "BD000300";
        sendHex(cmd);
    }

    /***ISO 与 国军标协议一致
     * 保存设置
     ***/

    @Override
    public void HSURM_SAVE_SETTING(CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String cmd = "BD000E00";
        sendHex(cmd);
    }

    /***ISO 与 国军标协议一致
     * 恢复出厂设置
     ***/
    @Override
    public void HSURM_RESTORE_SETTING(CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String cmd = "BD000F00";
        sendHex(cmd);
    }

    /***ISO 与 国军标协议一致
     * 占空比设置
     *  Inv_num：盘点轮空间隔次数；
     *  Inv_time：盘点轮空延时，ms 为单位
     ***/

    @Override
    public void HSURM_SET_DUTY_CYCLE(int Inv_num, int Inv_time, CallbackListener
            callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String a = Integer.toHexString(Inv_num);
        if (a.length() == 1) {
            a = "0" + a;
        }
        StringBuilder b = new StringBuilder(Integer.toHexString(Inv_time));
        while (b.length() < 8) {
            b.insert(0, "0");
        }

        String cmd = "BD001005" + a + b;
        sendHex(cmd);

    }

    /***ISO 与 国军标协议一致
     * 获取占空比
     ***/

    @Override
    public void HSURM_GET_DUTY_CYCLE(CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String cmd = "BD001100";
        sendHex(cmd);
    }

    /***ISO 与 国军标协议一致 但 国军标支持的链路索引只有两种，详见GJB 7737.1 协议
     *  设置射频通讯参数
     *  参数形式：int
     *  Proto（协议码）:
     * int "0" 代表 "00"--ISO18000-63;
     * int "1" 代表 "01"--GB/T29768;
     * int "2" 代表 "02"--GJB 7377.1;
     *
     	Rf_item：链路模式索引
     int "0"代表"00": 160KHz,FM0，Tari=12.5us
     int "1"代表"01": 160Khz Miller8，Tari=12.5us
     int "2"代表"02": 250Khz FM0，Tari=12.5us
     int "3"代表"03":320Khz Miller4，Tari=6.25us
     其他暂不支持
     ****/
    @Override
    public void HSURM_Set_RF_Prm(int Proto, int Rf_item, CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String to = "0" + Integer.toHexString(Proto);
        String item = "0" + Integer.toHexString(Rf_item);
        String Set_RF_Prm = "BD008306" + to + item + "00000000";
        sendHex(Set_RF_Prm);
    }


    /***ISO 与 国军标协议一致
     *  获取射频通讯参数
     *  参数形式：int
     *  Proto（协议码）:
     * int "0" 代表 "00"--ISO18000-63;
     * int "1" 代表 "01"--GB/T29768;
     * int "2" 代表 "02"--GJB 7377.1;
     *
     ***/
    @Override
    public void HSURM_Get_RF_Prm(int Proto, CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String to = "0" + Integer.toHexString(Proto);
        String Get_RF_Prm = "BD008401" + to;
        sendHex(Get_RF_Prm);

    }


    /***ISO 与 国军标协议一致
     * 设置/读取模块配置的协议掩码
     * 参数形式：int
     *   Option：命令控制选项
     * =1 代表 0x01：设置； 即"01"
     * =2 代表0x02：读取； 即"02"
     * 其他值：无效
     *   Proto_mask：协议掩码，是以下协议掩码值组合而来，取值范围大于0且小于等于7。
     * =1 代表ISO 18000-63协议为0x01； 即"01"
     * =2 代表 GB/T 29768协议为0x02；  即"02"
     * =4 代表 GJB 7377.1协议为0x04；  即"04"
     **/
    @Override
    public void SET_PROTO_MASK(int Option, int Proto_MAsk, CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String a = Integer.toHexString(Option);
        if (a.length() == 1) a = "0" + a;
        String b = Integer.toHexString(Proto_MAsk);
        if (b.length() == 1) b = "0" + b;
        String Set_Get_Proto_Mask_0 = "BD000C02" + a + b;
        sendHex(Set_Get_Proto_Mask_0);
    }

    /***ISO 与 国军标协议一致
     * Proto_Mask :  NC
     */
    @Override
    public void GET_PROTO_MASK(CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String Set_Get_Proto_Mask_1 = "BD000C0102";
        sendHex(Set_Get_Proto_Mask_1);
    }

    /***ISO 与 国军标协议一致
     * 设置天线使能* 单天线模块
     *  Antenna：按位表示选择使用的天线，对应 Bit 位值为 1 则表示使用该天线，值为 0 则表示不
     * 使用该天线；
     */
    @Override
    public void SET_ANTENNA(int Antenna, CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String a = Integer.toHexString(Antenna);
        if (a.length() == 1) a = "0" + a;
        String SET_ANTENNA = "BD000801" + a;
        sendHex(SET_ANTENNA);
    }

    /***ISO 与 国军标协议一致
     * 获取天线
     */
    @Override
    public void GET_ANTENNA(CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String GET_ANTENNA = "BD000900";
        sendHex(GET_ANTENNA);
    }

    /***ISO 与 国军标协议一致
     * 按时间盘点-国际标准标签盘点
     *  参数形式：int
     *  InvType：盘点方式
     InvType =1 :0x10：按时间盘点标签，在持续指定时间后停止盘点；（过滤盘点）
     InvType =2 :0x00：按时间盘点标签，在持续指定时间后停止盘点；
     * 其他值：无效；
     	InvParam：盘点方式对应的参数。
     盘点方式参数：
     当 InvType 为 0x10 时，InvParam 表示盘点时间，单位为：秒，如果该值为 0，则表示持续
     盘点标签，直到接收到停止盘点命令；
     */
    @Override
    public void HSURM_INVENTORYISO_CONTINUE_TIME(int InvType,
                                                 int InvParam, RFID_Callbacklistener rfid_callbacklistener) {
        //按时间盘点 时间单位 秒

        clean_pandian();
        SerialHelper.rfid_callbacklistener = rfid_callbacklistener;
        String a = Integer.toHexString(InvParam);
        int b = 8 - a.length();
        for (int i = 0; i < b; i++) {
            a = "0" + a;
        }
        if (InvType == 1) {//时间过滤盘点
            String Inventory = "BD00810510" + a;
            sendHex(Inventory);
        } else if (InvType == 2) { //时间盘点
            String Inventory = "BD00810500" + a;
            sendHex(Inventory);
        }
    }

    /***ISO 协议
     * 自定义盘点-国际标准标签盘点
     *  参数形式：int
     *  InvType：盘点方式
     InvType =1 : 0x03：使用自定义盘点参数盘点标签，接收到停止盘点命令后停止盘点；
     InvType =2 : 0x13：使用自定义盘点参数盘点标签，接收到停止盘点命令后停止盘点；（过滤盘点）
     * 其他值：无效；
     	InvParam：盘点方式对应的参数。
     盘点方式参数：
     InvParam 表示盘点条件，第一个字节表示会话，第二个字节表示存盘标识，第三字节表示 Sel，
     会话值如下：
     int huihua =0 代表 0x00：S0；
     int huihua =1 代表0x01：S1；
     int huihua =2 代表0x02：S2；
     int huihua =3 代表0x03：S3；
     存盘标识值如下：
     int AB =0 代表 0x00：A；
     int AB =1 代表0x01：B。
     Sel 值如下：
     int Sel=0 代表 0x00：ALL；
     int Sel=1 代表 0x01：ALL。
     int Sel=2 代表 0x02：~SL；
     int Sel=3 代表 0x03：SL。
     * */
    @Override
    public void HSURM_INVENTORYISO_CONTINUE_customize(int InvType, int huihua, int AB,
                                                      int Sel, RFID_Callbacklistener rfid_callbacklistener) {
        SerialHelper.rfid_callbacklistener = rfid_callbacklistener;
        clean_pandian();
        if (InvType == 1) { //自定义
            String St_huihua = "0" + Integer.toHexString(huihua);
            String St_AB = "0" + Integer.toHexString(AB);
            String St_Sel = "0" + Integer.toHexString(Sel);
            String Inventory = "BD00810503" + St_huihua + St_AB + St_Sel;
            String cmd = Inventory + "00";
            Log.e("TAG", "HSURM_INVENTORYISO_CONTINUE_customize: " + cmd);
            sendHex(cmd);
        } else if (InvType == 2) {  //自定义
            String St_huihua = "0" + Integer.toHexString(huihua);
            String St_AB = "0" + Integer.toHexString(AB);
            String St_Sel = "0" + Integer.toHexString(Sel);
            String Inventory = "BD00810513" + St_huihua + St_AB + St_Sel;
            String cmd = Inventory + "00";
            Log.e("TAG", "HSURM_INVENTORYISO_CONTINUE_customize: " + cmd);
            sendHex(cmd);
        }

    }

    /***ISO 协议
     * 停止盘点
     **/
    @Override
    public void HSURM_STOP_INVENTORY() {
        reciveClean();
        clean_readbuffer();
        write_clean();
        other_clean();
        clean_pandian();
        CMDType = 1;
        String STOP = "BD005D00";
        sendHex(STOP);
    }

    @Override
    public void HSURM_STOP_READ_TAG() {
        reciveClean();
        clean_readbuffer();
        write_clean();
        other_clean();
        clean_pandian();
        CMDType = 4;
        String STOP = "BD005D00";
        sendHex(STOP);
    }

    /***ISO 与 国军标协议一致
     * 设置在位天线射频输出功率
     * 传入参数形式：int
     *  功率值：范围为[10, 33]
     ***/
    @Override
    public void HSURM_Set_ANT_PWR(int power, CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String a = Integer.toHexString(power);
        if (power > 9 && power < 34) {
            if (a.length() == 1) {
                a = "0" + a;
                String Set_ANT_PWR = "bd0015030001" + a;
                sendHex(Set_ANT_PWR);
            } else if (a.length() == 2) {
                String Set_ANT_PWR = "bd0015030001" + a;
                sendHex(Set_ANT_PWR);
            }
        } else {
            SerialHelper.callbackListener.callback(false, "设置功率超出范围值");
        }
    }

    /***ISO 与 国军标协议一致
     * 获取在位天线射频输出功率
     */
    @Override
    public void HSURM_Get_ANT_PWR(CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String Get_ANT_PWR = "BD001600";
        sendHex(Get_ANT_PWR);
    }

    /***ISO 与 国军标协议一致
     * 设置射频工作频率
     * 参数形式：int
     *  int Proto（协议码）:
     * =0 代表 "x000"--ISO18000-63;
     * =1 代表 "x001"--GB/T29768;
     * =2 代表 "x002"--GJB 7377.1;
     *  int REGION（地域索引）:
     * =0 代表 x000：CHINA-2；
     * =1 代表 x001：FCC；
     * =2 代表 x002：JAPAN；（暂不支持）
     * =3 代表 x003：MALAYSIA；（暂不支持）
     * =4 代表 x004：ETSI；
     * =5 代表 x005：CHINA-1；
     * =6 代表 x006：自定义；
     *  int StartFrei（兆赫兹起始频率的整数部分）:如920.125MHz，STRATFREI =920，高字节=0x03，低字节=0x98；即"0398"
     *  int StartFred（兆赫兹起始频率的小数部分）:如920.125MHz，STRATFRED =125，高字节=0x00，低字节=0x7D；即"007D"
     *  int StepFre（频率步进KHz）:如125KHz，STEPFRE =125，高字节=0x4，低字节=0xE2；即"04E2"
     *  int CN（信道数）:
     * 信道数大于1则说明设置模块以"跳频工模式"，
     * 信道数等于1则说明设置模块以"定频工作模式"
     ***/
    @Override
    public void HSURM_Multi_Set_Fre(int Proto, int REGION, String Frei,
                                    int StepFre, int CN, CallbackListener callbackListener) {
        String St_StartFrei = null;  //兆赫兹起始频率的整数部分
        String St_StartFred = null;  //兆赫兹起始频率的小数部分
        String St_StepFre = null;    //频率步进KHz
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String Multi_Set_Fre_0 = "BD008509";
        String St_Proto = "0" + Integer.toHexString(Proto);
        String St_REGION = "0" + Integer.toHexString(REGION);

        if (Frei.contains(".")) {
            String[] FRECY = Frei.split("\\.", 2);
            int a_a_a = Integer.parseInt(FRECY[0]);
            String St_StartFrei_a = Integer.toHexString(a_a_a);
            if (St_StartFrei_a.length() == 1) {
                St_StartFrei = "000" + St_StartFrei_a;
            } else if (St_StartFrei_a.length() == 2) {
                St_StartFrei = "00" + St_StartFrei_a;
            } else if (St_StartFrei_a.length() == 3) {
                St_StartFrei = "0" + St_StartFrei_a;
            }
            int b_b_b = Integer.parseInt(FRECY[1]);
            String St_StartFred_a = Integer.toHexString(b_b_b);
            if (St_StartFred_a.length() == 1) {
                St_StartFred = "000" + St_StartFred_a;
            } else if (St_StartFred_a.length() == 2) {
                St_StartFred = "00" + St_StartFred_a;
            } else if (St_StartFred_a.length() == 3) {
                St_StartFred = "0" + St_StartFred_a;
            }
        } else {
            int c_c_c = Integer.parseInt(Frei);
            String St_StartFrei_a = Integer.toHexString(c_c_c);
            if (St_StartFrei_a.length() == 1) {
                St_StartFrei = "000" + St_StartFrei_a;
            } else if (St_StartFrei_a.length() == 2) {
                St_StartFrei = "00" + St_StartFrei_a;
            } else if (St_StartFrei_a.length() == 3) {
                St_StartFrei = "0" + St_StartFrei_a;
            }

            St_StartFred = "0000";
        }

        String St_StepFre_a = Integer.toHexString(StepFre);
        if (St_StepFre_a.length() == 1) {
            St_StepFre = "000" + St_StepFre_a;
        } else if (St_StepFre_a.length() == 2) {
            St_StepFre = "00" + St_StepFre_a;
        } else if (St_StepFre_a.length() == 3) {
            St_StepFre = "0" + St_StepFre_a;
        }
        String St_CN;
        if (Integer.toHexString(CN).length() == 1) {
            St_CN = "0" + Integer.toHexString(CN);
        } else {
            St_CN = Integer.toHexString(CN);
        }

        String Multi_Set_Fre = Multi_Set_Fre_0 + St_Proto + St_REGION + St_StartFrei + St_StartFred + St_StepFre + St_CN;
        Log.e("TAG", "HSURM_Multi_Set_Fre: " + Multi_Set_Fre);
        if (Multi_Set_Fre.length() == 26) {
            sendHex(Multi_Set_Fre);
        } else {
            Log.e("TAG", "HSURM_Multi_Set_Fre: " + "数据格式错误");
        }
    }

    /***ISO 与 国军标协议一致
     * 获取射频工作频率
     * 参数形式：int
     * int Proto（协议码）:
     *Proto = 0 代表 0x00：ISO 18000-63；
     *Proto = 1 代表 0x01：GB/T 29768；
     *Proto = 2 代表 0x02：GJB 7377.1；
     * 其他值无效
     * */
    @Override
    public void HSURM_Multi_Get_Fre(int Proto, CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;
        reciveClean();
        String St_Proto = "0" + Integer.toHexString(Proto);
        String Multi_Get_Fre_0 = "BD008601";
        String Multi_Get_Fre = Multi_Get_Fre_0 + St_Proto;
        sendHex(Multi_Get_Fre);
    }

    /**
     * ISO  协议
     * 选择标签
     * 参数类型：String
     * 传入标签UII。
     */
    @Override
    public void HSURM_SELECTMASK(String UII, CallbackListener callbackListener) {
        reciveClean();
        Select = true;
        SerialHelper.callbackListener = callbackListener;
        int len = (UII.length() / 2) * 8;
        String lens = "0";
        if (Integer.toHexString(len).length() == 1) {
            lens = "0" + Integer.toHexString(len);
        } else {
            lens = Integer.toHexString(len);
        }
        String all_len = Integer.toHexString(len / 8 + 3);
        if (all_len.length() == 1) {
            all_len = "0" + all_len;
        }


        String selectmask = "BD006B" + all_len + "0000" + lens + UII;
        sendHex(selectmask);
    }

    /**
     * ISO  协议
     * 选择标签
     * 参数类型：String
     * 传入标签UII。
     */
    @Override
    public void HSURM_SELECTMASK_CANCLE(CallbackListener callbackListener) {
        reciveClean();
        Select = false;
        SerialHelper.callbackListener = callbackListener;
        String selectmask = "BD006B" + "03" + "000000";
        sendHex(selectmask);
    }

    /**
     * ISO 和国军标协议一致
     * 读取标签
     * pro_mask :当前模块配置的协议掩码,该掩码必须和HSURM_SET_GET_PROTO_MASK 命令配置的协议掩码保持一致
     * ISO : (int) 0 ;
     * GJB : (int) 4 ;
     * Param：OpParam操作方式对应的参数,长度4byte；
     * （int）  0    表示   0x00：循环读取
     * Option：命令选项，按位指示数据读取方式
     * （int） 0 表示 00b：不进行安全认证
     * AccPwd：访问口令，例如00000000h；16进制字符串
     * MemBank：所要读取标签的存储区，值列表如下（针对 ISO 协议）：
     * （int） 0 表示 0x00：Reserved；
     * （int） 1 表示 0x01：EPC 或 UII；
     * （int） 2 表示 0x02：TID；
     * （int） 3 表示 0x03：User；
     * WordPtr：指向逻辑存储区的读取起始地址；
     * WordCount：需要读取的字个数；
     */
    @Override
    public void HSURM_READ_TAG(int pro_mask, int Param, int Option, String AccPwd, int MemBank, int WordPtr,
                               int WordCount, Read_Callbacklistener read_callbacklistener) {
        SerialHelper.read_callbacklistener = read_callbacklistener;
        clean_readbuffer();
        String membank = "";
        String mask = "0" + Integer.toHexString(pro_mask);
        String param = Integer.toHexString(Param);
        for (int i = param.length(); i < 8; i++) {
            param = "0" + param;
        }
        String option = "0" + Integer.toHexString(Option);
        if (Integer.toHexString(MemBank).length() == 1) {
            membank = "0" + Integer.toHexString(MemBank);
        } else {
            membank = Integer.toHexString(MemBank);
        }
        String wordptr = Integer.toHexString(WordPtr);
        for (int c = wordptr.length(); c < 4; c++) {
            wordptr = "0" + wordptr;
        }
        String wordcount = Integer.toHexString(WordCount);
        if (wordcount.length() == 1) {
            wordcount = "0" + wordcount;
        }

        String READ_TAG = "BD00820F" + mask + "00" + param + option + AccPwd + membank + wordptr + wordcount;
        sendHex(READ_TAG);
    }
    /**ISO && GJB : (int) 5 **/
    /**
     * ISO 和国军标协议一致
     * 读取标签
     * pro_mask :当前模块配置的协议掩码,该掩码必须和HSURM_SET_GET_PROTO_MASK 命令配置的协议掩码保持一致
     * ISO && GJB : (int) 5 ;
     * Param：OpParam操作方式对应的参数,长度4byte；
     * （int）  0    表示   0x00：循环读取
     * R1:ISO协议
     * Option：命令选项，按位指示数据读取方式
     * （int） 0 表示 00b：不进行安全认证
     * AccPwd：访问口令，例如00000000h；16进制字符串
     * MemBank：所要读取标签的存储区，值列表如下（针对 ISO 协议）：
     * （int） 0 表示 0x00：Reserved；
     * （int） 1 表示 0x01：EPC 或 UII；
     * （int） 2 表示 0x02：TID；
     * （int） 3 表示 0x03：User；
     * WordPtr：指向逻辑存储区的读取起始地址；
     * WordCount：需要读取的字个数；
     * R2:GJB协议
     * * Option：命令选项，按位指示数据读取方式
     * * （int） 0 表示 00b：不进行安全认证
     * * AccPwd：访问口令，例如00000000h；16进制字符串
     * * MemBank：所要读取标签的存储区，值列表如下（针对 ISO 协议）：
     * * （int） 0 表示 0x00：Reserved；
     * * （int） 1 表示 0x01：EPC 或 UII；
     * * （int） 2 表示 0x02：TID；
     * * （int） 3 表示 0x03：User；
     * * WordPtr：指向逻辑存储区的读取起始地址；
     * * WordCount：需要读取的字个数；
     */
    @Override
    public void HSURM_READ_ISO_GJB_TAG(int pro_mask, int Param,
                                       int OptionR1, String AccPwdR1, int MemBankR1, int WordPtrR1, int WordCountR1,
                                       int OptionR2, String AccPwdR2, int MemBankR2, int WordPtrR2, int WordCountR2,
                                       Read_Callbacklistener read_callbacklistener) {
        SerialHelper.read_callbacklistener = read_callbacklistener;
        clean_readbuffer();
        String membankR1 = "";
        String membankR2 = "";
        String mask = "0" + Integer.toHexString(pro_mask);
        String param = Integer.toHexString(Param);
        for (int i = param.length(); i < 8; i++) {
            param = "0" + param;
        }
        String optionR1 = "0" + Integer.toHexString(OptionR1);
        if (Integer.toHexString(MemBankR1).length() == 1) {
            membankR1 = "0" + Integer.toHexString(MemBankR1);
        } else {
            membankR1 = Integer.toHexString(MemBankR1);
        }
        String wordptrR1 = Integer.toHexString(WordPtrR1);
        for (int c = wordptrR1.length(); c < 4; c++) {
            wordptrR1 = "0" + wordptrR1;
        }
        String wordcountR1 = Integer.toHexString(WordCountR1);
        if (wordcountR1.length() == 1) {
            wordcountR1 = "0" + wordcountR1;
        }

        String optionR2 = "0" + Integer.toHexString(OptionR2);
        if (Integer.toHexString(MemBankR2).length() == 1) {
            membankR2 = "0" + Integer.toHexString(MemBankR2);
        } else {
            membankR2 = Integer.toHexString(MemBankR2);
        }
        String wordptrR2 = Integer.toHexString(WordPtrR2);
        for (int c = wordptrR2.length(); c < 4; c++) {
            wordptrR2 = "0" + wordptrR2;
        }
        String wordcountR2 = Integer.toHexString(WordCountR2);
        if (wordcountR2.length() == 1) {
            wordcountR2 = "0" + wordcountR2;
        }


        String READ_TAG = "BD008218" + mask + "00" + param +
                optionR1 + AccPwdR1 + membankR1 + wordptrR1 + wordcountR1 +
                optionR2 + AccPwdR2 + membankR2 + wordptrR2 + wordcountR2;
        sendHex(READ_TAG);
    }


    /**
     * ISO  协议
     * 写标签
     * 写标签之前必须先选中标签，调用HSURM_SELECTMASK方法；
     * Option：命令选项，按位指示数据写入方式
     * （int） 0 表示 00b：不进行安全认证
     * （int） 1 表示01b：进行安全认证
     * （int） 2 表示10b：使用安全通信
     * AccPwd：访问口令，例如00000000（h）；16进制字符串
     * MemBank：所要写入标签的存储区，值列表如下（针对 ISO 协议）：
     * （int） 0 表示 0x00：Reserved；
     * （int） 1 表示 0x01：EPC 或 UII；
     * （int） 2 表示 0x02：TID；
     * （int） 3 表示 0x03：User；
     * WordPtr：指向逻辑存储区的写入起始地址；
     * WordCount：需要写入的字个数； 1字 = 2byte
     * Data 表示要写入的数据，16进制 例如："01 E2 15 02"
     */
    @Override
    public void HSURM_WRITEISO_TAG(int Option, String AccPwd, int MemBank, int WordPtr,
                                   int WordCount, String Data, CallbackListener callbackListener) {
        breakout_write = false;
        write_clean();
        String lens = "0";
        SerialHelper.callbackListener = callbackListener;
        int len = Data.length() / 2 + 9;
        if (Integer.toHexString(len).length() == 1) {
            lens = "0" + Integer.toHexString(len);
        } else {
            lens = Integer.toHexString(len);
        }
        String option = "0" + Integer.toHexString(Option);
        String membank = "0" + Integer.toHexString(MemBank);
        String wordptr = Integer.toHexString(WordPtr);
        for (int c = wordptr.length(); c < 4; c++) {
            wordptr = "0" + wordptr;
        }
        String wordcount = Integer.toHexString(WordCount);
        if (wordcount.length() == 1) {
            wordcount = "0" + wordcount;
        }
        String WriteComd = "BD005F" + lens + option + AccPwd + membank + wordptr + wordcount + Data;
        sendHex(WriteComd);

        ANNR_write();
    }

    /**
     * ISO  协议
     * 锁定
     *  AccPwd：访问口令，用于标签进入安全态，如果访问口令不是 00000000h，则模块在发送 Lock
     * 指令之前，会先发送 Access 命令；如果访问口令是 00000000h，则模块不会发送 Access 命令；
     *  Area：需要锁定的区域，值列表如下：
     * (int) 0 代表 0x00：灭活密码区；
     * (int) 1 代表 0x01：访问密码区；
     * (int) 2 代表 0x02：UII 区；
     * (int) 3 代表 0x03：TID 区；
     * (int) 4 代表 0x04：User 区；
     *  Action：锁定操作类型，值列表如下；
     * (int) 0 代表 0x00：开放；
     * (int) 1 代表 0x01：永久开放；
     * (int) 2 代表 0x02：锁定；
     * (int) 3 代表 0x03：永久锁定；
     **/
    @Override
    public void HSURM_LOCKISO_TAG(String AccPwd, int Area, int Action, CallbackListener
            callbackListener) {
        other_clean();
        SerialHelper.callbackListener = callbackListener;
        String area = "0" + Integer.toHexString(Area);
        String action = "0" + Integer.toHexString(Action);
        String lock_cmd = "BD006006" + AccPwd + area + action;
        sendHex(lock_cmd);
    }

    /**
     * ISO  协议*
     * killpassword : 灭活密码
     **/
    @Override
    public void HSURM_KILLISO_TAG(String killpassword, CallbackListener callbackListener) {
        other_clean();
        SerialHelper.callbackListener = callbackListener;
        String kill_cmd = "BD006104" + killpassword;
        sendHex(kill_cmd);
    }

    /**
     * ISO  协议 和国军标一致
     * <p>
     * <p>
     * 温度设置
     * 范围：50℃-90℃
     **/
    @Override
    public void HSURM_TEMPERATURE_SET(int tem, CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String value = Integer.toHexString(tem);
        String settem = "BD001302" + value + "00";
        sendHex(settem);
    }

    /**
     * ISO  协议 和国军标一致
     * 温度获取
     **/

    @Override
    public void HSURM_TEMPERATURE_GET(CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String tem = "BD001400";
        sendHex(tem);
    }

    /**
     * ISO  协议 和国军标一致
     * 获取日志
     **/
    @Override
    public void HSURM_READ_LOG(CallbackListener callbackListener) {
        reciveClean();
        SerialHelper.callbackListener = callbackListener;
        String log = "BD00DD00";
        sendHex(log);
    }

    /**
     * 国军标部分****************************
     * <p>
     * 写标签 （待测试）
     * 协议参数参考ISO写标签
     *******/

    @Override
    public void HSURM_WRITEGB_TAG(int Option, String AccPwd, int MemBank, int WordPtr, int WordCount, String Data, CallbackListener callbackListener) {
        breakout_write = false;
        write_clean();
        String lens = "0";
        SerialHelper.callbackListener = callbackListener;
        int len = Data.length() / 2 + 9;
        if (Integer.toHexString(len).length() == 1) {
            lens = "0" + Integer.toHexString(len);
        } else {
            lens = Integer.toHexString(len);
        }
        String option = "0" + Integer.toHexString(Option);
        String membank = Integer.toHexString(MemBank);
        if (membank.length() == 1) {
            membank = "0" + membank;
        }
        String wordptr = Integer.toHexString(WordPtr);
        for (int c = wordptr.length(); c < 4; c++) {
            wordptr = "0" + wordptr;
        }
        String wordcount = Integer.toHexString(WordCount);
        if (wordcount.length() == 1) {
            wordcount = "0" + wordcount;
        }
        String WriteComd = "BD0044" + lens + option + AccPwd + membank + wordptr + wordcount + Data;
        sendHex(WriteComd);
        ANNR_write();
    }

    /**
     * 国军标
     * <p>
     * 停止盘点
     **/
    @Override
    public void HSURM_STOP_GJB() {
        reciveClean();
        clean_readbuffer();
        write_clean();
        other_clean();
        clean_pandian();
        CMDType = 1;
        String STOP = "BD003D00";
        sendHex(STOP);
    }

    /**
     * 国军标
     * <p>
     * 停止读
     **/
    @Override
    public void HSURM_STOP_READ_GJB() {
        reciveClean();
        clean_readbuffer();
        write_clean();
        other_clean();
        clean_pandian();
        CMDType = 4;
        String STOP = "BD003D00";
        sendHex(STOP);
    }


    /**
     * 国军标擦标签
     * <p>
     * * Option：命令选项，默认不进行安全认证 默认值为（int）0；
     *  AccPwd：密码
     *  MemBank：所要擦除的标签的存储区，值列表如下：
     * 1) 0x00：标签信息区；
     * 2) 0x10：编码区；
     * 3) 0x20：安全区；
     * 4) ≥0x30 并且≤0x3F：用户区，0x30 表示用户子区 0，0x31 表示用户子区 1，依次
     * 类推；
     *  WordPtr：指向逻辑存储区的擦除起始地址；
     *  WordCount：需要擦除的字个数，该参数允许为 0；
     **/
    @Override
    public void HSURM_ERASEGB_TAG(int Option, String AccPwd, int MemBank, int WordPtr, int WordCount, CallbackListener callbackListener) {
        SerialHelper.callbackListener = callbackListener;

        clean_GJBbuffer();
        String option = "0" + Integer.toHexString(Option);
        String membank = Integer.toHexString(MemBank);
        String wordptr = Integer.toHexString(WordPtr);
        for (int c = wordptr.length(); c < 4; c++) {
            wordptr = "0" + wordptr;
        }
        String wordcount = Integer.toHexString(WordCount);
        if (wordcount.length() == 1) {
            wordcount = "0" + wordcount;
        }

        String ERASEGB = "BD004509" + option + AccPwd + membank + wordptr + wordcount;
        sendHex(ERASEGB);
    }

    /**
     * 国军标锁标签
     * <p>
     *  AccPwd：锁定口令，长度为 4 字节；
     *  MemBank：所要锁定的标签的存储区，值列表如下：
     * 1) 0x00：标签信息区；
     * 2) 0x10：编码区；
     * 3) 0x20：安全区；
     * 4) ≥0x30 并且≤0x3F：用户区，0x30 表示用户子区 0，0x31 表示用户子区 1，依次
     * 类推；
     *  Cfg：用于指定是配置存储区属性还是配置安全模式，值列表如下：
     * 1) 0x00：配置存储区属性；
     * 2) 0x01：配置安全模式，该模式下 MemBank 字段必须为 0x20（安全区），否则返回
     * 响应的状态码为 0x01（参数值错误或越界）；
     *  Action：锁定类型；
     * 如果 Cfg 字段为 0x00，指示对指定逻辑存储区进行的锁定操作，值列表如下：
     * 1) 0x00：对应逻辑存储区锁定为可读可写；
     * 2) 0x01：对应逻辑存储区锁定为可读不可写；
     * 3) 0x02：对应逻辑存储区锁定为不可读可写；
     * 4) 0x03：对应逻辑存储区锁定为不可读不可写；
     * 5) 其他值：系统保留；
     * 如果 Cfg 字段为 0x01，指示对安全模式的配置操作，值列表如下：
     * 1) 0x01：不需要认证；
     * 2) 0x02：需要认证，不需要安全通信；
     * 3) 0x03：需要认证，需要安全通信。
     * 4) 其他值：系统保留；
     **/
    @Override
    public void HSURM_LOCKGB_TAG(String AccPwd, int MemBank, int Cfg, int Action, CallbackListener callbacklistener) {
        other_clean();
        SerialHelper.callbackListener = callbacklistener;
        String area = Integer.toHexString(MemBank);
        if (area.length() == 1) {
            area = "0" + area;
        }
        String cfg = "0" + Integer.toHexString(Cfg);
        String action = "0" + Integer.toHexString(Action);
        String lock_cmd = "BD004607" + AccPwd + area + cfg + action;
        sendHex(lock_cmd);
    }

    /**
     * 国军标
     * <p>
     * 灭活标签
     * killpassword: 灭活密码
     **/
    @Override
    public void HSURM_KILLGB_TAG(String killpassword, CallbackListener callbacklistener) {
        other_clean();
        SerialHelper.callbackListener = callbacklistener;
        String kill_cmd = "BD004704" + killpassword;
        sendHex(kill_cmd);
    }

    /**
     * 国军标
     * <p>
     * 选择标签
     * 参数类型：String
     * 传入标签UII。
     */
    @Override
    public void HSURM_SELECTMASK_GJB(String UII, CallbackListener callbackListener) {
        reciveClean();
        Select = true;
        SerialHelper.callbackListener = callbackListener;
        int len = (UII.length() / 2) * 8;
        String lens = "0";
        if (Integer.toHexString(len).length() == 1) {
            lens = "0" + Integer.toHexString(len);
        } else {
            lens = Integer.toHexString(len);
        }
        String all_len = Integer.toHexString(len / 8 + 3);
        if (all_len.length() == 1) {
            all_len = "0" + all_len;
        }


        String selectmask = "BD004B" + all_len + "0000" + lens + UII;
        sendHex(selectmask);
    }

    /**
     * ISO
     * <p>
     * 设置Select指令参数
     */
    @Override
    public void HSURM_SET_SELPRM(String protocal, String target, String truncate, String action, int memBank, String pointer, int mask, CallbackListener callbackListener) {
        reciveClean();
        Select = true;
        SerialHelper.callbackListener = callbackListener;
        String lens = Integer.toHexString(mask * 8);
        String masks = "";
        if ((mask * 8) % 2 == 1) {
            masks = Integer.toHexString(mask) + "0";
        } else {
            masks = Integer.toHexString(mask);
        }
        String selectmask = "BD0087" + FuncUtil.toStringHex(protocal) + FuncUtil.toStringHex(target) + FuncUtil.toStringHex(truncate) + FuncUtil.toStringHex(action) + Integer.toHexString(memBank) + FuncUtil.toStringHex(pointer) + lens + masks;
        sendHex(selectmask);
    }

    /**
     * ISO
     * <p>
     * 获取Select指令参数
     */
    @Override
    public void HSURM_GET_SELPRM(String protocal, CallbackListener callbackListener) {
        reciveClean();
        Select = true;
        SerialHelper.callbackListener = callbackListener;
        String getSelprm = "BD0088" + FuncUtil.toStringHex(protocal);
        sendHex(getSelprm);
    }


    /**
     * ISO
     * <p>
     * //测温功能v1.0 设置标签类型
     */
    @Override
    public void HSURM_MODBUS_SET_TAG_TYPE(int tagType, CallbackListener callbackListener) {
        clean_readtempbuffer();
        SerialHelper.callbackListener = callbackListener;
        String tagtype = "0" + Integer.toHexString(tagType);
        String getSelprm = "BD002C" + "01" + tagtype;
        sendHex(getSelprm);
    }

    /**
     * ISO
     * <p>
     * //测温功能v1.0 获取标签类型
     */
    @Override
    public void HSURM_MODBUS_GET_TAG_TYPE(CallbackListener callbackListener) {
        clean_readtempbuffer();
        SerialHelper.callbackListener = callbackListener;
        String getSelprm = "BD002D" + "00";
        sendHex(getSelprm);
    }

    /**
     * ISO
     * <p>
     * //测温功能v1.0 读取国际标准协议标签数据
     */
    @Override
    public void HSURM_READISO_TAG(int Option, String AccPwd, int MemBank, int WordPtr, int WordCount, Temp_Callbacklistener temp_callbacklistener) {

        clean_pandiantemp();
        SerialHelper.temp_callbacklistener = temp_callbacklistener;
        String option = "0" + Integer.toHexString(Option);
        String membank = "0" + Integer.toHexString(MemBank);
        String wordCountStr = "0" + Integer.toHexString(WordCount);
        String wordptr = Integer.toHexString(WordPtr);

        for (int c = wordptr.length(); c < 4; c++) {
            wordptr = "0" + wordptr;
        }
        if (WordCount == 0 && membank != "01") {
            for (int c = 0; c < wordptr.length(); c++) {
                wordptr = "0" + wordptr;
            }
        }
        if (WordCount == 0 && membank == "01") {
            for (int c = wordptr.length(); c < 4; c++) {
                wordptr = "0" + wordptr;
            }
        }
        //"BD005E09000000000003000801"
        String READISO = "BD005E09" + option + AccPwd + membank + wordptr + wordCountStr;
        sendHex(READISO);
    }

    @Override
    public void HSURM_STOP_READTEMP() {
        reciveClean();
        clean_pandiantemp();
        CMDType = 7;
        String STOP = "BD005D00";
        sendHex(STOP);
    }


    /**
     * 国军标
     * <p>
     * 取消选择标签
     * 参数类型：String
     * 传入标签UII。
     */
    @Override
    public void HSURM_SELECTMASK_CANCLE_GJB(CallbackListener callbackListener) {
        reciveClean();
        Select = false;
        SerialHelper.callbackListener = callbackListener;
        String selectmask = "BD004B" + "03" + "000000";
        sendHex(selectmask);
    }


    @Override
    public void callback(boolean success, String msg) {

    }

    @Override
    public void rfid_Callback(boolean success, String result) {
    }

    private String Erdata(byte data) {
        switch (data) {
            case 0x00:
                return "成功";

            case 0x01:
                return "失败：参数值错误";

            case 0x02:
                return "失败：硬件平台内部错误";

            case 0x12:
                return "命令执行完成";

            case 0x16:
                return "失败：模块未连接";

            case 0x17:
                return "失败：数据超出串口最大传输长度";
        }
        return "错误参数异常";
    }

}